package com.mtech.modbus_rtu.data._10;

import com.mtech.modbus_rtu.data.base.ModbusDataGram;
import com.mtech.modbus_rtu.data.base.ModbusFunction;
import com.mtech.modbus_rtu.util.ByteUtils;

/**
 * 多笔写入命令
 * 
 * @author lixiaolong
 * @CreateDate 2018年3月20日
 */
public class MultiWriteTxDataGram extends ModbusDataGram {
	protected static final int WRITE_LENGTH = 0x01;//单笔写入

	protected int registerAddr;//寄存器起始地址
	protected int length;//写入笔数(寄存器个数)
	protected int[] values;

	public MultiWriteTxDataGram(byte addr, int registerAddr, int[] values) {
		this(addr, ModbusFunction.MULTI_WRITE, registerAddr, values);
	}

	/**
	 * 写入
	 * 
	 * @param addr
	 *            设备地址
	 * @param fun
	 *            单笔或多笔
	 * @param registerAddr
	 *            起始寄存器地址
	 * @param values
	 *            值数组
	 */
	protected MultiWriteTxDataGram(byte addr, ModbusFunction fun, int registerAddr, int[] values) {
		super(addr, fun.getCode());
		this.registerAddr = registerAddr;
		this.length = values.length;
		this.values = values;
		this.datas = madeDatas();
		this.check = checkDataBytes();
	}

	/**
	 * 用报文来构造对象
	 * 
	 * @param buf
	 */
	public MultiWriteTxDataGram(byte[] buf) {
		super(buf);
		decode(buf);
	}

	/**
	 * 多笔解码
	 * 
	 * @Author lixiaolong
	 * @CreateDate
	 * @param buf
	 */
	protected void decode(byte[] buf) {
		//start
		this.registerAddr = ByteUtils.bytes2Int(buf, 0, 2);
		//length
		this.length = ByteUtils.bytes2Int(buf, 2, 2);
		//values
		this.values = new int[this.length];
		for (int i = 5, j = 0; i < this.datas.length; i = i + 2, j++) {
			int value = ByteUtils.bytes2Int(this.datas, i, 2);
			this.values[j] = value;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.mtech.aircdx.datagram.data.ModbusDataGram#madeDatas()
	 */
	@Override
	protected byte[] madeDatas() {
		return encode();
	}

	/**
	 * 多笔写入
	 * 
	 * @Author lixiaolong
	 * @CreateDate
	 * @return
	 */
	protected byte[] encode() {
		//寄存器数量
		int length = this.values.length;//==this.length;
		byte[] datas = new byte[2 + 2 + 1 + length * 2];
		//start
		byte[] startBytes = ByteUtils.int2Bytes(this.registerAddr, 2);
		datas[0] = startBytes[0];
		datas[1] = startBytes[1];
		//length
		byte[] lengthBytes = ByteUtils.int2Bytes(length, 2);
		datas[2] = lengthBytes[0];
		datas[3] = lengthBytes[1];
		//byteCount
		byte byteCount = ByteUtils.int2Bytes(length * 2, 1)[0];
		datas[4] = byteCount;
		//values
		for (int i = 0; i < this.values.length; i++) {
			byte[] valueBytes = ByteUtils.int2Bytes(this.values[i], 2);
			datas[5 + 2 * i] = valueBytes[0];
			datas[6 + 2 * i] = valueBytes[1];
		}
		return datas;
	}

	public int getRegisterAddr() {
		return registerAddr;
	}

	public void setRegisterAddr(int registerAddr) {
		this.registerAddr = registerAddr;
	}

	public int getLength() {
		return length;
	}

	public void setLength(int length) {
		this.length = length;
	}

	public int[] getValues() {
		return values;
	}

	public void setValues(int[] values) {
		this.values = values;
	}

}
